package com.record.service.impl;



import com.record.dto.*;
import com.record.entity.Formula;
import com.record.mapper.FormulaMapper;
import com.record.mapper.IngreMapper;
import com.record.mapper.TasteMapper;
import com.record.service.TasteService;
import com.record.vo.FangjiKeVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class TasteServiceImpl implements TasteService {

    @Autowired
    private TasteMapper tasteMapper;

    @Autowired
    private IngreMapper ingreMapper;

    @Autowired
    private FormulaMapper formulaMapper;


    @Override
    public FormulaSixDto getTasteName(String TasteName) {
        return tasteMapper.getTasteName(TasteName);
    }

    @Override
    public List<IndexedValue> getWeight(String Zufang) {
        FormulaSixDto formulaSixDto = tasteMapper.getTasteName(Zufang);
        //根据组方查询其中的六味

        if (formulaSixDto == null) {
            System.out.println("⚠️ 未查询到对应的组方数据，请检查参数：" + Zufang);
            return Collections.emptyList(); // 返回空列表
            // 或者直接抛出异常：
            // throw new RuntimeException("未查询到对应的组方数据，请检查参数：" + Zufang);
        }

        Integer x1 = formulaSixDto.getTasteId1();
        Integer x2 = formulaSixDto.getTasteId2();
        Integer x3 = formulaSixDto.getTasteId3();
        Integer x4 = formulaSixDto.getTasteId4();
        Integer x5 = formulaSixDto.getTasteId5();
        Integer x6 = formulaSixDto.getTasteId6();

        List<Integer> values = new ArrayList<>();
        if (x1 != null) values.add(x1);
        if (x2 != null) values.add(x2);
        if (x3 != null) values.add(x3);
        if (x4 != null) values.add(x4);
        if (x5 != null) values.add(x5);
        if (x6 != null) values.add(x6);

        int maxIndex = values.size(); // 最大序号

        List<IndexedValue> indexedValues = new ArrayList<>();
        for (int i = 0; i < values.size(); i++) {
            indexedValues.add(new IndexedValue(i + 1, values.get(i), maxIndex));
        }

        return indexedValues;
    }

    /**
     * 根据组方查询六味的权重
     *
     * @param Zufang
     * @return
     */
    @Override
    public TotalWeightDto getTotallyWeight(String Zufang) {
        // 1. 获取剂量
        List<IngredientDTO> ingredients = ingreMapper.getIngredientByName(Zufang);
        if (ingredients == null || ingredients.isEmpty()) {
            throw new RuntimeException("未查询到剂量数据，请检查参数：" + Zufang);
        }
        // 这里取第一个剂量（你之前用 get(1)，注意 Java 下标是从 0 开始）
        Double Jiliang = ingredients.get(0).getDosage();

        // 2. 获取 formulaSixDto
        FormulaSixDto formulaSixDto = tasteMapper.getTasteName(Zufang);
        if (formulaSixDto == null) {
            throw new RuntimeException("未查询到对应的组方数据，请检查参数：" + Zufang);
        }

        // 3. 收集非空 tasteId
        List<Integer> values = new ArrayList<>();
        if (formulaSixDto.getTasteId1() != null) values.add(formulaSixDto.getTasteId1());
        if (formulaSixDto.getTasteId2() != null) values.add(formulaSixDto.getTasteId2());
        if (formulaSixDto.getTasteId3() != null) values.add(formulaSixDto.getTasteId3());
        if (formulaSixDto.getTasteId4() != null) values.add(formulaSixDto.getTasteId4());
        if (formulaSixDto.getTasteId5() != null) values.add(formulaSixDto.getTasteId5());
        if (formulaSixDto.getTasteId6() != null) values.add(formulaSixDto.getTasteId6());

        // 最大 index
        int maxIndex = values.size();

        // 4. 应用公式 n * [6 + maxIndex*(maxIndex+1)/2]
        double result = Jiliang * (6 + (maxIndex * (maxIndex + 1) / 2.0));

        // 封装进 DTO
        TotalWeightDto totalWeightDto = new TotalWeightDto();
        totalWeightDto.setTotalWeight(result);
        totalWeightDto.setJiliang(Jiliang);

        return totalWeightDto;

    }


    @Override
    public FangjiWeightDto getFangjiWeight(String Fangji) {
        // 先判空，避免传入空参数
        if (Fangji == null || Fangji.trim().isEmpty()) {
            throw new IllegalArgumentException("参数 Fangji 不能为空！");
        }

        Formula formula = formulaMapper.selectFormulaWithIngredients(Fangji);

        // 判空 formula 或 ingredients
        if (formula == null || formula.getIngredients() == null || formula.getIngredients().isEmpty()) {
            throw new RuntimeException("未查询到对应的方剂或组方药材数据，请检查参数：" + Fangji);
        }

        // 收集药材名
        List<String> ingredientNames = formula.getIngredients()
                .stream()
                .map(FormulaIngredientDto::getIngredientName)
                .filter(Objects::nonNull) // 过滤掉 null 值
                .collect(Collectors.toList());

        if (ingredientNames.isEmpty()) {
            throw new RuntimeException("方剂中未包含有效药材，请检查参数：" + Fangji);
        }

        double totalResult = 0.0;

        // 遍历 ingredientNames
        for (String Zufang : ingredientNames) {
            // 1. 获取剂量
            List<IngredientDTO> ingredients = ingreMapper.getIngredientByName(Zufang);
            if (ingredients == null || ingredients.isEmpty()) {
                // 没有剂量数据就跳过
                continue;
            }
            Double Jiliang = ingredients.get(0).getDosage();
            if (Jiliang == null) {
                // 剂量为空也跳过
                continue;
            }

            // 2. 获取 formulaSixDto
            FormulaSixDto formulaSixDto = tasteMapper.getTasteName(Zufang);
            if (formulaSixDto == null) {
                // 没有对应的组方，跳过，不要报错
                continue;
            }

            // 3. 收集非空 tasteId
            List<Integer> values = new ArrayList<>();
            if (formulaSixDto.getTasteId1() != null) values.add(formulaSixDto.getTasteId1());
            if (formulaSixDto.getTasteId2() != null) values.add(formulaSixDto.getTasteId2());
            if (formulaSixDto.getTasteId3() != null) values.add(formulaSixDto.getTasteId3());
            if (formulaSixDto.getTasteId4() != null) values.add(formulaSixDto.getTasteId4());
            if (formulaSixDto.getTasteId5() != null) values.add(formulaSixDto.getTasteId5());
            if (formulaSixDto.getTasteId6() != null) values.add(formulaSixDto.getTasteId6());

            int maxIndex = values.size();

            double result = Jiliang * (6 + (maxIndex * (maxIndex + 1) / 2.0));

            totalResult += result;
        }

        FangjiWeightDto fangjiWeightDto = new FangjiWeightDto();
        fangjiWeightDto.setFangjiWeight(totalResult);

        return fangjiWeightDto;
    }

    /**
     * 根据组方查询其味道的总量
     *
     * @param fangjiKeVo
     * @return
     */
    @Override
    public FangjiKeDto getFangjike(String fangjiKeVo) {
        //根据fangjiKeVo中的Fangji参数查询所有的组方
        // 先判空，避免传入空参数
        if (fangjiKeVo == null || fangjiKeVo.trim().isEmpty()) {
            throw new IllegalArgumentException("参数 Fangji 不能为空！");
        }

        Formula formula = formulaMapper.selectFormulaWithIngredients(fangjiKeVo);
        if (formula == null || formula.getIngredients() == null || formula.getIngredients().isEmpty()) {
            throw new RuntimeException("未查询到对应的方剂的组方药材数据，请检查参数：" + fangjiKeVo);
        }

        List<FormulaIngredientDto> ingredientList = new ArrayList<>();
        //根据组方查询其中所有的权重
        List<IndexedValue> allIndexedValues = new ArrayList<>();

        if (formula != null && formula.getIngredients() != null) {
            for (FormulaIngredientDto ingredient : formula.getIngredients()) {

                // 存入集合
                ingredientList.add(ingredient);
            }

            for (FormulaIngredientDto dto : ingredientList) {
                String herbName = dto.getIngredientName();   // 药材名
                Double herbDosage = dto.getDosage();         // 药材剂量

                // 根据 herbName 查询六味
                // 根据 herbName 查询六味
                FormulaSixDto tasteInfo = tasteMapper.getTasteName(herbName);

                // 定义 tasteIds，默认空
                List<Integer> tasteIds = new ArrayList<>();

                if (tasteInfo != null) {
                    if (tasteInfo.getTasteId1() != null) tasteIds.add(tasteInfo.getTasteId1());
                    if (tasteInfo.getTasteId2() != null) tasteIds.add(tasteInfo.getTasteId2());
                    if (tasteInfo.getTasteId3() != null) tasteIds.add(tasteInfo.getTasteId3());
                    if (tasteInfo.getTasteId4() != null) tasteIds.add(tasteInfo.getTasteId4());
                    if (tasteInfo.getTasteId5() != null) tasteIds.add(tasteInfo.getTasteId5());
                    if (tasteInfo.getTasteId6() != null) tasteIds.add(tasteInfo.getTasteId6());
                } else {
                    // 找不到 tasteInfo，也要继续计算，可以只打印提示
                    System.out.println("⚠️ 未查询到对应的组方数据，已忽略: " + herbName);
                }
                int maxCount = tasteIds.size(); // 六味的有效个数

                // 封装 IndexedValue（加上 herbName 和 herbDosage）
                for (int i = 0; i < tasteIds.size(); i++) {
                    allIndexedValues.add(
                            new IndexedValue(i + 1, tasteIds.get(i), maxCount, herbName, herbDosage)
                    );
                }
            }
        }


        // 初始化返回对象
        FangjiKeDto fangjiKeDto = new FangjiKeDto();

        // 分组
        Map<Integer, List<IndexedValue>> grouped = allIndexedValues.stream()
                .collect(Collectors.groupingBy(IndexedValue::getValue));

        // 保存处理后的结果
        List<Map<String, Object>> dtoResults = new ArrayList<>();

        for (Map.Entry<Integer, List<IndexedValue>> entry : grouped.entrySet()) {
            Integer value = entry.getKey();
            List<IndexedValue> values = entry.getValue();

            // 累加 result
            int sumResult = values.stream()
                    .mapToInt(IndexedValue::getResult)
                    .sum();

            // dosage（取第一个，如果同组有多个 dosage 不同，可改成平均或相加）
            double dosage = values.get(0).getHerbDosage();

            // 计算总值
            double finalResult = sumResult * dosage;

            // index（取第一个，或者 list 的大小都行）
            int index = values.get(0).getIndex();

            // 封装到一个 Map（或者你可以新建一个 Dto）
            Map<String, Object> item = new HashMap<>();
            item.put("value", value);
            item.put("sumResult", sumResult);
            item.put("dosage", dosage);
            item.put("index", index);
            item.put("finalResult", finalResult);

            dtoResults.add(item);
        }


        // 把结果塞进返回对象（假设 FangjiKeDto 里有个 List<Map<String,Object>> 字段）
        fangjiKeDto.setResults(dtoResults);

        return fangjiKeDto;
    }




}



